
Title : A True LB API Popup Menu.
By : Duncan Bushaw
Published on : March 22, 2007.
Last Edit on March 24, 2007.

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------In this article I will be explaining how I used the following 12 API functions; CheckMenultem, CheckMenuRadioltem, CreatePopupMenu, DestroyMenu, EnableMenuttem, HiliteMenultem, lnsertMenultem, SetMenuDefaultltem, SetMenulnfo, SetMenultemBitmaps, SetMenultemlnfo, TrackPopupMenuEx, and 3 API structures;MENUINFO, MENUITEMINFO, and TPMPARAMS, and how they work together in the example "Classic Face Clock.-bas". Which is a graphicbox in a popup window with an API popupmenu called with the event handler of the grapicbox.

I will also be describing some of the neat things that can be done with a popupmenu that I discovered while I was writting the example program.


When you first start the example program it will begin with the default setting set for all options. The size of the clock will be medium with a buttonface background, in this mode and larger modes the date and AM/PM indicater will be shown, in the small mode just numbers and hands are shown.

When the example program runs it first creates an unnamed windows that is 0x0 in size. The purpose of the window is; 1) to be able to load image files into memory using Alcye Watsons' jpeg.dll before creating the main program window. 2) to pass this windows handle to the HiliteMenuItem function call, because if the main program window handle is used some of the menuitems that are hilighted by the dll call get painted to the main program window, using the dummy window prevents that from happening.

After creating the dummy window the example program loads the images into memory using either Alcye Watsons' jpeg.dll or the LB Loadbmp command. If the menuitem [ Options > Load .bmp Only (resets menu) ] is checked then the example program loads images using the LB command.

The example program then creates the popupmenu, whose handles is kept in the variable MPM, every enabled or maybe enabled later menuitem in the popupmenu should have a different ID number assigned to it at this time which is then returned with the TrackPopupMenuEx dll call. Not all menuitems in the example program have different ID numbers, all seperators I assigned the number zero as it can not be selected it will not return the number, all other menuitems are assigned a unique number between 1 and 65535.

The program is designed to make it as easy as possible to move the menuitems around so as to change the layout of the popup menu when it is called, without having to rewrite alot of other code to make it work. This also applies to moving menuitems from one assigned menu to another.
	
By moving these two lines only ;

z=z+1 ' Increment counter.

null=InsertMenuItem(y,z,0,0,46,SMNMI,0,0,"0 - Enabled",0) ' Insert menuitem.

[y] hMenu, is the handle to the menu to put the menuitem in.
[z] uItem, is the position counter for inserting the menuitem and is used to ensure that the next menuitem is inserted at the bottom of the menu.
[0] fType, The type of menuitem.
[0] fState, The state of the menuitem.
[46] wID, is the ID number to assign.
[SMNMI] hSubMenu, the handle of a sub-menu.
[0] hbmpChecked, the handle to the 12x12 bitmap image to use if the menuitem is checked.
[0] hbmpUnchecked, the handle to the 12x12 bitmap image to use if the menuitem is unchecked.
["0 - Enabled"] dwTypeData$, The text to put into the menuitem.
[0] hbmpItem,  the handle to the image to use.

Because all function calls other then HiliteMenuItem(hwnd,hmenu,uItemHilite,uHilite)  and SetMenuDefaultItem(hMenu,uItem) do not use the assigned menu handle to work correctly but are called with the MPM handle they do not need to be changed if changing the menu layout HiliteMenuItem(hwnd,hmenu,uItemHilite,uHilite)  and SetMenuDefaultItem(hMenu,uItem) must be used with the menu handle that actually contains the menuitem.
 
When inserting menuitems into a submenu they do not need to be in the order of their ID numbers. To modify a menuitem in the example program they are accessed by the ID number and not by the menu position, except for HiliteMenuItem(hwnd,hmenu,uItemHilite,uHilite)  and SetMenuDefaultItem(hMenu,uItem). This makes rearranging menuitems in a popupmenu easy to do without having to change a lot of code, even if it is from one submenu to another.

More than one menuitem in a submenu may be hilighted or set as a default item. Menuitems that are hilighted with the dll call remain hilighted untill the mouse moves over them. Only the first default menuitem in a submenu is valid. If the default menuitems have been marked then double clicking on the ' Preferences ' menuitem will cause the ' Preferences > Top Most ' menuitem to be either checked or unchecked as if that was that menuitem that had been clicked by the mouse.

Holding the right button down and moving it from above the clock to another portion of the screen and then releasing the button will cause the menu to be centered to mouse. Right click on the clock to call the menu Which will then be displayed in two ways depending on if the ' Preferences > Top Most ' menuitem is checked or not. If the menuitem ' Preferences > Top Most ' setting is checked then the clock is displayed above all other windows and the menu will not appear above or over the clock, if possible. This is done by the sending a structure containing the coordinates of a rectangle to be excluded in the TrackPopupEx dLL call which tells the system not to put the menu in that rectangle. If the menuitem ' Preferences > Top Most ' setting is not checked then the clock is not displayed above all other windows and the menu will appear over the clock so the menu is centered to mouse.

When changing the clock size the clock window will close and then reopen centered to the mouse, this was done so that the clock will always have a portion shown on the monitor after resizing.

Mouse Event Handlers. Only 4 graphicbox event handlers are used in the program.

-when leftButtonDown [Down] - The program will hide the mouse and then get the current position of the mouse and save it in a temperary variable that is used to help reposition the clock window.

-when leftButtonMove [Move] - The program will get the current position of the mouse and using the temperary variable repositions the clock window.

-when leftButtonUp [Up] - The program will save the program settings so the new position of the clock window is stored and then show the mouse.

-when rightButtonUp [Menu] - The program will highlight all the menuitems set for highlighting. There are 2 mmenuitems on the main popup menu that are highlighted both of these are in a disabled state but are not grayed. The other menuitems that are highlighted are the current clock size and color settings.

The following is a discription of the menuitems in the Options sub-menu.

- Load .bmp only (resets menu) - When checked makes the program only load image files with the .bmp extention using the LB command LOADBMP, When it is unchecked the program will load all images using Alyce Watson's jpeg.dll. When selected the program destroys the menu and deletes the images from memory before rebuilding the menu, all unsaved options will be reset. This is a saved option.

- MNS_CHECKORBMP - When checked the menuitem images and the checkmark images will appear in the same column, if a menuitem has both uncheckmark bmp handle assigned and a menuitem image handle assigned only the uncheckmark image will be seen and the height of the menuitem will be that of the menuitem image. This is a saved option.

- Disable/Enable Examples Menu - When selected will either disable or enable the Examples sub-menu. This is an unsaved option.

- Unmark/Mark Default Menuitems -  When selected will either Unmark or Mark the default menuitems. This is an unsaved option.

- Remove/Install Checkmark BMP's - When selected will either remove or install the checkmark and uncheckmark images. This is an unsaved option.

- Remove/Install Menuitem BMP's - When selected will either remove or install the menuitem images. This is an unsaved option.

- View "Classic Face Clock.txt" File. - When selected the program will open, for veiwing, the settings file using the systems default text editor.

I need to talk about the TrackPopupMenuEx dll call. If you compare my translation of the C syntax you will notice that in C the return value is BOOL (Boolean in LB) but my translation it is Long and not Boolean. The reason for this is that if Boolean is used a 'Key is missing' error happens and the dll call fails to work, but changing it to long allows it to work. I believe it has to do with the fact that the way the dll is called so it returns the wID number which can be a very large number, Boolean perhaps can't handle such large numbers. All I can say is that it works so 'nuff said.

This is just a brief description of what I did, open the bas file and you will find that it is full of rem statements describing each step thru the program. I could go on for pages describing things that I did in the program.

What follows in the article are 3 appendices:
Appendix A ; The Windows API DLL calls.
Appendix B ; The Windows API Structures.
Appendix C ; The CFC API Popup Menu Tree.



